﻿using CPAIS.Adapter;
using CPAIS.Model;
using CPAIS.Updater;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.SessionState;

namespace CPAIS.Web.AjaxHandlers
{
    public class TestAnalysisSpeedHandler : AjaxHandler
    {
        public TestAnalysisSpeedHandler(HttpContext context) : base(context) { }
        
        /// <summary>
        /// AJAX request:
        ///     TestAnalysisSpeed
        /// 
        /// Request Parameters:
        ///     logName
        ///     parts
        ///     defaultK
        ///     topicNo
        ///     
        /// Response:
        ///     None
        ///     
        /// </summary>
        #region Ajax Request TestAnalysisSpeed

        public void TestAnalysisSpeed()
        {
            string logName = Params[Constants.LogName];
            MLManager mlManager = Session[Constants.MLManager] as MLManager;
            TestCPMAnalysisSpeedAdapter adapter = mlManager.GetTASAdapter(logName);
            AnalysisUpdater updater = new AnalysisUpdater(Session, adapter,
                int.Parse(Params[Constants.Parts]),
                int.Parse(Params[Constants.DefaultK]),
                int.Parse(Params[Constants.TopicNo]));
            Session.Add(Constants.TestAnalysisSpeedUpdater, updater);
            ThreadPool.QueueUserWorkItem(DoTesting, updater);
        }

        private class AnalysisUpdater : ProgressUpdater
        {
            public HttpSessionState Session { get; set; }
            public TestCPMAnalysisSpeedAdapter Adapter { get; set; }
            public int Parts { get; set; }
            public int DefaultK { get; set; }
            public int TopicNo { get; set; }

            public AnalysisUpdater(HttpSessionState session, TestCPMAnalysisSpeedAdapter adapter, int parts, int defaultK, int topicNo)
            {
                this.Session = session;
                this.Adapter = adapter;
                this.Parts = parts;
                this.DefaultK = defaultK;
                this.TopicNo = topicNo;
            }

            protected override bool OnUpdateMessage(string message)
            {
                if (Session[Constants.TestAnalysisSpeedUpdater] != null)
                {
                    return true;
                }
                return false;
            }

            protected override bool OnUpdateProgress(double progress)
            {
                if (Session[Constants.TestAnalysisSpeedUpdater] != null)
                {
                    return true;
                }
                return false;
            }
        }
               
        private void DoTesting(object state)
        {
            AnalysisUpdater updater = state as AnalysisUpdater;
            TestCPMAnalysisSpeedAdapter adapter = updater.Adapter;
            adapter.Execute(updater.Parts, updater.DefaultK, updater.TopicNo, 0.1, 0.01, 0.01, 1000, updater);
        }
        
        #endregion

        /// <summary>
        /// AJAX request:
        ///     CancelLDAAnalysis
        /// 
        /// Request Parameters:
        ///     logName
        /// 
        /// Response:
        ///     None
        /// </summary>
        #region Ajax Request CancelTestAnalysisSpeed

        public void CancelTestAnalysisSpeed()
        {
            Session.Remove(Constants.TestAnalysisSpeedUpdater);
        }

        #endregion

        /// <summary>
        /// AJAX request:   
        ///     QueryLDAAnalysisProgress
        /// 
        /// Request Parameters:
        ///     logName
        /// 
        /// Response: 
        ///     QueryLDAAnalysisProgressPackage
        /// </summary>
        #region Ajax Request QueryTestAnalysisSpeedProgress

        public void QueryTestAnalysisSpeedProgress()
        {
            AnalysisUpdater updater = Session[Constants.TestAnalysisSpeedUpdater] as AnalysisUpdater;
            QueryTestAnalysisSpeedProgressPackage package = new QueryTestAnalysisSpeedProgressPackage
            {
                state = updater.State.ToString(),
                msg = updater.Message,
                progress = updater.Progress
            };
            switch (updater.State)
            {
                case UpdateState.Failed:
                case UpdateState.Completed:
                    Session.Remove(Constants.LDAAnalysisUpdater);
                    break;
            }
            WriteJson(package);
        }

        private class QueryTestAnalysisSpeedProgressPackage
        {
            public string state { get; set; }
            public string msg { get; set; }
            public double progress { get; set; }
        }

        #endregion


        /// <summary>
        /// AJAX request:
        ///     GetTestingResultWithTraceCount
        /// 
        /// Request Parameters:
        ///     logName
        /// 
        /// Response: 
        ///     TestingResultWithTraceCountPackage
        /// </summary>
        #region Ajax Request GetTestingResultWithTraceCount

        public void GetTestingResultWithTraceCount()
        {
            string path = Params[Constants.LogName];

            MLManager mlManager = Session[Constants.MLManager] as MLManager;
            TestCPMAnalysisSpeedAdapter adapter = mlManager.GetTASAdapter(path);
            List<TestingResultWithTraceCountPackage> packages = new List<TestingResultWithTraceCountPackage>();
            if (adapter != null)
            {
                long[] timeElapsed = adapter.TimeElapsedWithTraceCount;
                int[] traceCount = adapter.TraceCountWithTraceCount;
                for (int i = 0; i < timeElapsed.Length; i++)
                {
                    packages.Add(new TestingResultWithTraceCountPackage { traceCount = traceCount[i], timeElapsed = timeElapsed[i] });
                }
            }
            WriteJson(packages);
        }

        private class TestingResultWithTraceCountPackage
        {
            public int traceCount { get; set; }
            public double timeElapsed { get; set; }
        }

        #endregion



        /// <summary>
        /// AJAX request:
        ///     GetTestingResultWithTopicNo
        /// 
        /// Request Parameters:
        ///     logName
        /// 
        /// Response: 
        ///     TestingResultWithTopicNoPackage
        /// </summary>
        #region Ajax Request GetTestingResultWithTopicNo

        public void GetTestingResultWithTopicNo()
        {
            string path = Params[Constants.LogName];

            MLManager mlManager = Session[Constants.MLManager] as MLManager;
            TestCPMAnalysisSpeedAdapter adapter = mlManager.GetTASAdapter(path);
            List<TestingResultWithTopicNoPackage> packages = new List<TestingResultWithTopicNoPackage>();
            if (adapter != null)
            {
                long[] timeElapsed = adapter.TimeElapsedWithTopicNo;
                for (int i = 0; i < timeElapsed.Length; i++)
                {
                    packages.Add(new TestingResultWithTopicNoPackage { topicNo = i + 1, timeElapsed = timeElapsed[i] });
                }
            }
            WriteJson(packages);
        }

        private class TestingResultWithTopicNoPackage
        {
            public int topicNo { get; set; }
            public double timeElapsed { get; set; }
        }

        #endregion
    }
}